/* typehints:start */
import { GameRoot } from "./root";
/* typehints:end */

import { ArrUnique, clamp, copyObj, createID, getObjectType, getValueInArray, keepDecimal, ObjectDelKey, ObjectMapCb, randomChoice, randomChoiceNum } from "../core/utils/utils";
import { RaceDefine } from "./defines/race_define";
import { PeopleAttr } from "./people/people_attr";
import { LevelForceDefine, LevelXianDefine, prcaticeDiffDefine } from "./defines/level_define";
import { Goods } from "./goods/goods";
import SkillModules from "./skills/get_skill";
import { attrDefine } from "./defines/attr_define";

const _id = createID();

export class People{
  constructor(root, data){
    this.data = new PeopleAttr(data);

    /** @type {GameRoot} */
    this.root = root;
  }

  getName(){
    return this.data.name;
  }

  getRace(){
    return RaceDefine[this.data.race];
  }

  getGender(){
    return RaceDefine[this.data.race].gender[this.data.gender] || '未知';
  }

  /**
   * 修改世界定位
   * @param {*} pos 
   */
  setWorldPos(pos){
    this.data.worldPos = [parseInt(pos[0]), parseInt(pos[1])];
  }

  /**
   * 修改地区定位
   * @param {*} pos 
   */
  setMapPos(pos){
    this.data.mapPos = [parseInt(pos[0]), parseInt(pos[1])];
  }

  // 获取负重
  getWeightKg(){
    // 气血最大负重，因为身体的存储范围有限，其他保存需要使用背包道具
    let maxKg = clamp(~~(this.data.attr.blood * 10), 10, 200);
    this.getLimbs().map(item => {
      item.equips.map(item => {
        let attr = item.getDefaultAttr();
        let Inventory = attr[attrDefine.inventoryWeight.key];
        if(Inventory){
          maxKg += Inventory;
        }
      })
    });
    return maxKg;
  }

  // 获取自身的副业
  getSideHustle(key){
    return this.data.sideHustle.find(item => item.key == key);
  }

  // 获取修炼天资的文本
  getDiffDesc(){
    return getValueInArray(prcaticeDiffDefine, this.data.attr.practiceDiff).title;
  }

  getLevelDesc(type = 'xian'){
    let num = type === 'xian' ? this.data.xianNum : this.data.forceNum;
    let data = type === 'xian' ? LevelXianDefine : LevelForceDefine;

    return getValueInArray(data, num).title;
  }

  getLimbs(needLimbs = []){
    this.internalTransformLimbs();
    let limbs = this.data.limbs.map(limb => {
      // buff等对肢体的过滤
      limb.$power = limb.power;

      return limb;
    }).filter(item => {
      if(needLimbs.length <= 0) return true;

      return needLimbs.find(limb => limb.key == item.key);
    });

    return limbs;
  }

	getFirstIdentity() {
		let identity = this.data.identitys.sort((a, b) => {
			return b.level - a.level;
		})[0];

		if(identity){
			return identity.name;
		} else {
			return '';
		}
	}

  // 获取行动力
  // 行动力由敏捷、气血、神魂组成
  getActionNum(){
    let attr = this.data.attr;

    return attr[attrDefine.agile.key] + (attr[attrDefine.blood.key] * .5) + (attr[attrDefine.cons.key] * .1);
  }

  getSkill(key){
    return this.getSkills().find(item => item.key == key);
  }

  /**
   * 获取技能
   * @param {*} isShow 是否显示不能无法使用的技能
   * @returns 
   */
  getSkills(isShow = true){
    let skills = this.data.skills;

    // 将装备携带的技能放入
    let limbs = this.getLimbs();
    limbs.map(item => {
      item.equips.map(item => {
        skills = skills.concat(item.getSkills());
      })
    })

    return ArrUnique(skills).map(item => {
      if(!SkillModules[item]) return false;
      let skill = new SkillModules[item](this.root, this.data.skillsNum[item]);
      skill.key = item;
      return skill;
    }).filter(i => {
      if(isShow) return i;
      let flag = i && i.internalGetIsUse(this);
      
      return getObjectType(flag) === 'Boolean';
    });
  }

  getEquips(type = null){
    let limbs = this.getLimbs();

    return limbs.map(item => item.equips).flat(2).filter(item => {
      if(type === null) return true;
      return item instanceof type;
    })
  }

  /**
   * -----------------   内部方法   -----------------
   */

  // 转换肢体中的装备为实例
  internalTransformLimbs(){
		this.data.limbs.map(limb => {
			limb.equips = limb.equips.map((item, i) => {
        // 如果已经是goods就不用转换了
        if(item instanceof Goods) return item;
				let good = this.root.worldMap.getGood(item.key, item.attr);
				if(good){
          good.peopleLimb = limb;
          good.equipsIndex = i;
					return good;
				}
			}).filter(i => i);
		})
  }

	internalGetData(){
		this.data.limbs.map(limb => {
			limb.equips = limb.equips.map(item => {
        if(item instanceof Goods){
          return item.getData();
        } else {
          return item;
        }
			})
		})

		return copyObj(this.data);
	}
}